package com.turtle3d.user.grammars;

import java.util.ArrayList;

import com.turtle3d.formallanguage.grammar.Grammar;
import com.turtle3d.formallanguage.parser.SimpleParser;
import com.turtle3d.formallanguage.symbol.Method;
import com.turtle3d.formallanguage.symbol.Symbol;
import com.turtle3d.formallanguage.symbol.SymbolFactory;
import com.turtle3d.util.Randomizer;

/**
 * A tree with independently set growth radius and height. Branch angle variation.
 * @author Marek Paterczyk <marek.paterczyk@gmail.com>
 *
 */
public class Tree2 extends Grammar
{	
	
	public void define(){
		
		Symbol axiom = SymbolFactory.getSymbolFactory().createSymbolofClass("B");	
		setAxiom(axiom);												
				
		SymbolFactory.getSymbolFactory().registerSymbolClass("F", "F(grow)", new Method(){
			public boolean calculate(ArrayList<Symbol> symbolSequence, int symbolIndex, Symbol calculatedSymbol)
			{
				Float r = calculatedSymbol.getParameter("radius");
				Float r_mul = calculatedSymbol.getParameter("radiusMultiplier");
				calculatedSymbol.setParameter("radius", r*r_mul);
				
				Float d = calculatedSymbol.getParameter("distance");
				Float d_mul = calculatedSymbol.getParameter("distanceMultiplier");
				calculatedSymbol.setParameter("distance", d*d_mul+(calculatedSymbol.getParameter("distanceVariation")*d*Randomizer.getRandomizer().nextVariation()));
				
				return true;
				
			}
		});				
		
		addProduction(SimpleParser.parseProduction("B->F[+RSB][>+RSB][>>+RSB][RB]"));
		addProduction(SimpleParser.parseProduction("F->F(grow)"));				
						
	}
	
	public void setRequiredParameters(){
		setRequiredParameter(Symbol.RADIUS, 0.15f);
		setRequiredParameter("radiusMultiplier", 1.7f);
		setRequiredParameter(Symbol.DISTANCE, 0.2f);
		setRequiredParameter("distanceMultiplier", 1.5f);				
		setRequiredParameter(Symbol.TURN_ANGLE, 45f);
		setRequiredParameter(Symbol.ROLL_ANGLE, 120f);		
		setRequiredParameter("distanceVariation", 0.2f);
		setRequiredParameter(Symbol.SCALE_MULTIPLIER, 0.9f);
	}

}
